
#include "485_protocol.h"
#include "device_parameter.h"
#include "led_board.h"
#include "basic_board.h"

/*** 全局/静态变量 ***/
static uint16_t payloadLength = 0; // payload长度
static uint8_t StateCode = 0; // 状态记录


/*** 全局/静态变量 结束 ***/

/*** 外部函数声明 ***/

/*** 外部函数声明 结束 ***/


/*** 专用 host协议组包,解包函数的实现 ***/
bool BuildOpenSpecificFoorFrameCallback(void *dataIn, uint8_t *data, uint16_t *len)
{
    PRINT("[485_protocol] : BuildOpenSpecificFoorFrameCallback \r\n");
    uint16_t index = 0;
    uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    BluetoothGetMacAddress(SrcMacAddress);
    uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(DestinMacAddress);
    
    if (dataIn != NULL && data != NULL && len != NULL && SrcMacAddress != NULL && DestinMacAddress != NULL)
    {
        ElectorData_t *electorData = (ElectorData_t *)dataIn;
        data[index++] = FRAME_HEADER1;
        data[index++] = FRAME_HEADER2;
        data[index++] = 0x00;                                  // data长度H为0
        data[index++] = ELECTOR_SUM_FLOOR_NUM_BUFFER_SIZE + 1; // data长度L为2
        data[index++] = CMD_OPEN_FOOR;
        memcpy(&data[index], SrcMacAddress, MAC_ADDR_CODING_LENGTH); // 源地址
        index += MAC_ADDR_CODING_LENGTH;
        memcpy(&data[index], DestinMacAddress, MAC_ADDR_CODING_LENGTH); // 目的地址
        index += MAC_ADDR_CODING_LENGTH;
        data[index++] = electorData->DirectModeFlag;//直达模式
        data[index++] = electorData->User;                                                      // 用户
        memcpy(&data[index], electorData->ElectorFloorData, ELECTOR_SUM_FLOOR_NUM_BUFFER_SIZE); // 楼层号
        index += ELECTOR_SUM_FLOOR_NUM_BUFFER_SIZE;
        data[index] = calculateChecksum(data, index);
        index++;
        *len = index;
        return true;
    }

    return false;
}
uint8_t ParsingOpenSpecificFoorFrameCallback(uint8_t *data, uint16_t len)
{
    if (data != NULL)
    {
        PRINT("[485_protocol] : ParsingOpenSpecificFoorFrameCallback \r\n");
        if (len == 1)
        {
            // 记录成功状态
            StateCode = data[0];
            if (StateCode == 0x01){
                // PromptSetCompleteStatus();
            }
            PRINT("[485_protocol] : ParsingOpenSpecificFoorFrameCallback :%02x\r\n", data[0]);
            return RS485_PARSING_SUCCESS;
        }
    }
    return RS485_PARSING_ERROR;
}

bool BuildFirmwareTransFrameCallback(void *dataIn, uint8_t *data, uint16_t *len)
{
    PRINT("[485_protocol] : BuildFirmwareTransFrameCallback \r\n");
    uint16_t index = 0;
    uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    BluetoothGetMacAddress(SrcMacAddress);
    uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(DestinMacAddress);
    if (dataIn != NULL && data != NULL && len != NULL){
        IoBoardFirmwareInfo_t *IoBoardFirmwareInfo = (IoBoardFirmwareInfo_t *)dataIn;
        data[index++] = FRAME_HEADER1;
        data[index++] = FRAME_HEADER2;
        uint16_t payloadLength = IoBoardFirmwareInfo->SinglePackageSendBufferSize + 4; // 计算payload长度，包括版本号
        data[index++] = (payloadLength & 0xFF00) >> 8; // data长度H为0
        data[index++] = payloadLength & 0x00FF; // data长度L为1
        data[index++] = CMD_FIRMWARE_TRANS;
        memcpy(&data[index], SrcMacAddress, MAC_ADDR_CODING_LENGTH); // 源地址
        index += MAC_ADDR_CODING_LENGTH;
        memcpy(&data[index], DestinMacAddress, MAC_ADDR_CODING_LENGTH); // 目的地址
        index += MAC_ADDR_CODING_LENGTH;
        data[index++] = (IoBoardFirmwareInfo->SumSentPackageNumber & 0xFF00) >> 8; // 总包数H
        data[index++] = IoBoardFirmwareInfo->SumSentPackageNumber & 0x00FF; // 总包数L
        data[index++] = (IoBoardFirmwareInfo->CurrentSendPackageSeqNumber & 0xFF00) >> 8; // 包序号长度H
        data[index++] = IoBoardFirmwareInfo->CurrentSendPackageSeqNumber & 0x00FF; // 包序号长度L
        memcpy(&data[index], IoBoardFirmwareInfo->SinglePackageSendBuffer, IoBoardFirmwareInfo->SinglePackageSendBufferSize); // 固件数据
        index += IoBoardFirmwareInfo->SinglePackageSendBufferSize;
        data[index] = calculateChecksum(data, index);
        index++;
        *len = index;
        return true;
    }
    return false;
}

bool ParsingFirmwareTransFrameCallback(uint8_t *data, uint16_t len)
{
    if (data != NULL)
    {
        PRINT("[485_protocol] : ParsingFirmwareTransFrameCallback \r\n");
        if (len == 1)
        {
            // 记录成功状态
            StateCode = data[0];
            PRINT("[485_protocol] : ParsingFirmwareTransFrameCallback :%02x\r\n", data[0]);
            if (StateCode == 0x01)
            {// 解析完成
                return RS485_PARSING_SUCCESS;
            }
        }
    }
    return RS485_PARSING_ERROR;
}

bool BuildQueryIoBoardFirmwareStatusCallback(void *dataIn, uint8_t *data, uint16_t *len)
{
    PRINT("[485_protocol] : BuildQueryIoBoardFirmwareStatusCallback \r\n");
    uint16_t index = 0;
    uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    BluetoothGetMacAddress(SrcMacAddress);
    uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(DestinMacAddress);

    if (dataIn!= NULL && data!= NULL && len!= NULL)
    {
        data[index++] = FRAME_HEADER1;
        data[index++] = FRAME_HEADER2;
        data[index++] = 0x00; // data长度H为0 
        data[index++] = 0x01; // data长度L为1
        data[index++] = CMD_QUERY_OTA_STATUS; // 命令
        memcpy(&data[index], SrcMacAddress, MAC_ADDR_CODING_LENGTH); // 源地址
        index += MAC_ADDR_CODING_LENGTH;
        memcpy(&data[index], DestinMacAddress, MAC_ADDR_CODING_LENGTH); // 目的地址
        index += MAC_ADDR_CODING_LENGTH;
        data[index] = calculateChecksum(data, index);
        index++;
        *len = index;
        return true;
    }
    return false;

}

bool ParsingQueryIoBoardFirmwareStatusCallback(uint8_t *data, uint16_t len)
{
    if (data!= NULL)
    {
        PRINT("[485_protocol] : ParsingQueryIoBoardFirmwareStatusCallback \r\n");
        if (len == 1)
        {
            // 记录响应状态
            StateCode = data[0];
            PRINT("[485_protocol] : ParsingQueryIoBoardFirmwareStatusCallback :%02x\r\n", data[0]);
            return RS485_PARSING_SUCCESS;
        } 
    }
    return RS485_PARSING_ERROR;
}

bool BuildQueryIoBoardMacAddressCallback(void *dataIn, uint8_t *data, uint16_t *len)
{
    PRINT("[485_protocol] : BuildQueryIoBoardMacAddressCallback \r\n");
    uint16_t index = 0;
    uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    BluetoothGetMacAddress(SrcMacAddress);
    uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(DestinMacAddress);
    
    if (dataIn != NULL && data != NULL && len != NULL)
    {
        uint8_t* ptr = (uint8_t *)dataIn;
        data[index++] = FRAME_HEADER1;
        data[index++] = FRAME_HEADER2;
        data[index++] = 0x00; // data长度H为0
        data[index++] = 0x01; // data长度L为1
        data[index++] = CMD_QUERY_IO_BOARD_MAC_ADDRESS; // 命令
        memcpy(&data[index], SrcMacAddress, MAC_ADDR_CODING_LENGTH); // 源地址
        index += MAC_ADDR_CODING_LENGTH; 
        memcpy(&data[index], DestinMacAddress, MAC_ADDR_CODING_LENGTH); // 目的地址
        index += MAC_ADDR_CODING_LENGTH;
        data[index++] = BasicGetDeviceActivationStatus(); // 数据
        data[index] = calculateChecksum(data, index);
        index++;
        *len = index;
        return true;
    }
    return false;
}

bool ParsingQueryIoBoardMacAddressCallback(uint8_t *data, uint16_t len)
{
    if (data!= NULL)
    {
        PRINT("[485_protocol] : ParsingQueryIoBoardMacAddress \r\n");
        if (len == MAC_ADDR_CODING_LENGTH)
        {
            // 记录查询到的主板的mac地址
            uint8_t MacAddress[MAC_ADDR_CODING_LENGTH] = {0};
            memcpy(MacAddress, data, MAC_ADDR_CODING_LENGTH);
            PRINT("[485_protocol] : ParsingQueryIoBoardMacAddress :\r\n"); 
            for (uint8_t i=0; i<MAC_ADDR_CODING_LENGTH; i++){
                PRINT("%02x ", MacAddress[i]); 
            }
            PRINT("\r\n");
            SetDestinMacAddress(MacAddress);
            return RS485_PARSING_SUCCESS;
        } 
    }
    return RS485_PARSING_ERROR;
}

bool BuildGetVersionFrameCallback(void *dataIn, uint8_t *data, uint16_t *len)
{
    PRINT("[485_protocol] : BuildGetVersionFrameCallback \r\n");
    uint16_t index = 0;
    uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    BluetoothGetMacAddress(SrcMacAddress);
    uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(DestinMacAddress);
    if (dataIn != NULL && data != NULL && len != NULL)
    {
        data[index++] = FRAME_HEADER1;
        data[index++] = FRAME_HEADER2;
        data[index++] = 0x00;
        data[index++] = 1;
        data[index++] = CMD_GET_VERSION;
        memcpy(&data[index], SrcMacAddress, MAC_ADDR_CODING_LENGTH); // 源地址
        index += MAC_ADDR_CODING_LENGTH;
        memcpy(&data[index], DestinMacAddress, MAC_ADDR_CODING_LENGTH); // 目的地址
        index += MAC_ADDR_CODING_LENGTH;
        data[index++] = 1;
        data[index] = calculateChecksum(data, index);
        index++;
        *len = index;
        return true;
    }

    return false;
}

bool ParsingGetVersionFrameCallback(uint8_t *dataIn, uint16_t len)
{
    if (dataIn != NULL)
    {
        PRINT("[485_protocol] : ParsingGetVersionFrameCallback ========99999\r\n");
        char *ptr = (char *)dataIn;
        if (len == NUMBER_OF_FIRMWARE_VERSION)
        {
            // SetIoBoardFirmwareVersionNumber(ptr);
            uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
            GetDestinMacAddress(DestinMacAddress);
            PRINT("[485_protocol] : DestinMacAddress[5] = %02x\r\n", DestinMacAddress[5]);
            SetIoBoardFirmwareVersionByTable(DestinMacAddress[5], ptr);

            char versionStr[NUMBER_OF_FIRMWARE_VERSION] = {0};
            GetIoBoardFirmwareVersionByTable(DestinMacAddress[5], versionStr);
            PRINT("[485_protocol] : versionStr = %s\r\n", versionStr);
            SetSupportIoBoardNumber(DestinMacAddress[5]);
            return RS485_PARSING_SUCCESS;
        }
    }
    return RS485_PARSING_ERROR;
}

bool BuildOpenEmergencyModeFrameCallback(void *dataIn, uint8_t *data, uint16_t *len)
{
    PRINT("[485_protocol] : BuildOpenEmergencyModeFrameCallback \r\n");
    uint16_t index = 0;
    uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    BluetoothGetMacAddress(SrcMacAddress);
    uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(DestinMacAddress);
    uint8_t *ptr = (uint8_t *)dataIn;
    if (ptr == NULL)
    {
        PRINT("[485_protocol] : BuildOpenEmergencyModeFrameCallback : dataIn is NULL \r\n");
        return false;
    }
    if (data == NULL)
    {
        PRINT("[485_protocol] : BuildOpenEmergencyModeFrameCallback : data is NULL \r\n");
        return false;
    }
    if (len == NULL)
    {
        PRINT("[485_protocol] : BuildOpenEmergencyModeFrameCallback : len is NULL \r\n");
        return false;
    }
    if (dataIn != NULL && data != NULL && len != NULL)
    {
        data[index++] = FRAME_HEADER1;
        data[index++] = FRAME_HEADER2;
        data[index++] = 0x00; // data长度H为0
        data[index++] = 0x01; // data长度L为1
        data[index++] = CMD_OPEN_EMERGENCY_MODE;
        memcpy(&data[index], SrcMacAddress, MAC_ADDR_CODING_LENGTH); // 源地址
        index += MAC_ADDR_CODING_LENGTH;
        memcpy(&data[index], DestinMacAddress, MAC_ADDR_CODING_LENGTH); // 目的地址
        index += MAC_ADDR_CODING_LENGTH;
        data[index++] = ptr[0]; // 数据
        data[index] = calculateChecksum(data, index);
        index++;
        *len = index;
        return true;
    }
    return true;
}

bool ParsingOpenEmergencyModeFrameCallback(uint8_t *data, uint16_t len)
{
    if (data != NULL)
    {
        PRINT("[485_protocol] : ParsingOpenEmergencyModeFrameCallback \r\n");
        if (len == 1)
        {
            // 记录成功状态
            StateCode = data[0];
            PRINT("[485_protocol] : ParsingOpenEmergencyModeFrameCallback :%02x\r\n", data[0]);
            return RS485_PARSING_SUCCESS;
        }
    }
    return RS485_PARSING_ERROR;
}

bool BuildSetBoardSelfTestFrameCallback(void *dataIn, uint8_t *data, uint16_t *len)
{
    PRINT("[485_protocol] : BuildOpenEmergencyModeFrameCallback \r\n");
    uint16_t index = 0;
    uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    BluetoothGetMacAddress(SrcMacAddress);
    uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
    GetDestinMacAddress(DestinMacAddress);
    uint8_t *ptr = (uint8_t *)dataIn;

    if (dataIn != NULL && data != NULL && len != NULL)
    {
        data[index++] = FRAME_HEADER1;
        data[index++] = FRAME_HEADER2;
        data[index++] = 0x00; // data长度H为0
        data[index++] = 0x01; // data长度L为1
        data[index++] = CMD_SET_BOARD_SELF_TEST;
        memcpy(&data[index], SrcMacAddress, MAC_ADDR_CODING_LENGTH); // 源地址
        index += MAC_ADDR_CODING_LENGTH;
        memcpy(&data[index], DestinMacAddress, MAC_ADDR_CODING_LENGTH); // 目的地址
        index += MAC_ADDR_CODING_LENGTH;
        data[index++] = ptr[0]; // 数据
        data[index] = calculateChecksum(data, index);
        index++;
        *len = index;
        return true;
    }
    return true;
}

bool ParsingSetBoardSelfTestFrameCallback(uint8_t *data, uint16_t len)
{
    if (data != NULL)
    {
        PRINT("[485_protocol] : ParsingOpenEmergencyModeFrameCallback \r\n");
        if (len == 1)
        {
            // 记录成功状态
            StateCode = data[0];
            PRINT("[485_protocol] : ParsingOpenEmergencyModeFrameCallback :%02x\r\n", data[0]);
            return RS485_PARSING_SUCCESS;
        }
    }
    return RS485_PARSING_ERROR;
}

/*** 专用 host协议组包,解包函数的实现 结束***/



/*** 通用函数 ***/

bool VerifyMessageValidity(uint8_t *DataBuffIn, uint8_t *AttachedDataOut, uint16_t *AttachedDataSizeOut, ParsingResult_t *ParsingResult, uint16_t *CurrentCommandOut)
{
    PRINT("[485_protocol] : VerifyMessageValidity \r\n");
    if (DataBuffIn == NULL || AttachedDataOut == NULL || AttachedDataSizeOut == NULL || ParsingResult == NULL || CurrentCommandOut == NULL)
    {
        *ParsingResult = ERROR_NULL_PTR;
        return false;
    }

    if (DataBuffIn[0] == FRAME_HEADER1 && DataBuffIn[1] == FRAME_HEADER2)
    {
        payloadLength = (DataBuffIn[2] << 8) | DataBuffIn[3];
        PRINT("[485_protocol] :payloadLength = %d\r\n", payloadLength);
        uint8_t cmd = DataBuffIn[4];

        // 获取源地址
        uint8_t SrcMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
        PRINT("[485_protocol] : SrcMacAddress = \r\n");
        memcpy(SrcMacAddress, &DataBuffIn[5], MAC_ADDR_CODING_LENGTH);
        for (uint8_t i = 0; i < MAC_ADDR_CODING_LENGTH; i++)
        {
            PRINT("%02x ", SrcMacAddress[i]);
        }
        PRINT("\r\n"); 


        // 获取目的地址
        uint8_t DestinMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
        PRINT("[485_protocol] : DestinMacAddress = \r\n");
        memcpy(DestinMacAddress, &DataBuffIn[11], MAC_ADDR_CODING_LENGTH);
        for (uint8_t i = 0; i < MAC_ADDR_CODING_LENGTH; i++)
        {
            PRINT("%02x ", DestinMacAddress[i]);
        }
        PRINT("\r\n");

        uint8_t BluetoothMacAddress[MAC_ADDR_CODING_LENGTH] = {0};
        BluetoothGetMacAddress(BluetoothMacAddress);

        if (memcmp(BluetoothMacAddress, DestinMacAddress, MAC_ADDR_CODING_LENGTH) != 0)
        {
            // 不是给我的
            PRINT("[485_protocol] : DestinMacAddress error\r\n");
            *ParsingResult = ERROR_DESTIN_ADDR_ERROR;
            return false;
        }

        uint8_t checksum = DataBuffIn[payloadLength + 5 + 12];
        if (payloadLength > 0 && payloadLength <= MESSAGE_DATA_PACKET_LENGTH - 1)
        {
            if (checksum == calculateChecksum(DataBuffIn, payloadLength + 5 + 12))
            {
                *CurrentCommandOut = cmd;
                *ParsingResult = NO_ERROR;
                *AttachedDataSizeOut = payloadLength;
                memcpy(AttachedDataOut, &DataBuffIn[5+12], payloadLength);
                return true;
            }
            else
            {
                PRINT("[485_protocol] : checksum error checksum = %02x, calculateChecksum = %02x\r\n", checksum, calculateChecksum(DataBuffIn, payloadLength + 5 + 12));
                *ParsingResult = ERROR_FRAME_CHECKSUM_ERROR;
                return false;
            }
        }
        else
        {
            *ParsingResult = ERROR_FRAME_LENGTH_ERROR;
            return false;
        }
    }
    else
    {
        *ParsingResult = ERROR_FRAME_HEADER_ERROR;
    }

    return false;
}

uint8_t calculateChecksum(uint8_t *data, uint8_t length)
{
    uint8_t sum = 0;
    for (uint8_t i = 0; i < length; i++)
    {
        sum += data[i];
    }
    return sum & 0xFF;
}

/*** 通用函数 结束 ***/
